package org.dei.perla.rockfall;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;

import org.dei.dataserver.Server;
import org.dei.perla.parser.expressions.Constant;
import org.dei.perla.parser.expressions.ConstantID;
import org.dei.perla.parser.grammar.ParseException;
import org.dei.perla.parser.grammar.Parser;
import org.dei.perla.parser.statements.Query;
import org.dei.perla.parser.util.PairValue;
import org.dei.perla.rockfall.utils.DatabaseDump;
import org.dei.perla.rockfall.utils.IntecDatabaseDump;
import org.dei.perla.sys.device.fpc.FPC;
import org.dei.perla.sys.device.fpc.dspic.DSPicFPC;
import org.dei.perla.sys.device.fpc.intec.IntecFpc;
import org.dei.perla.sys.llqruntime.QueryAnalyzer;
import org.dei.perla.utils.PerlaRuntime;

public class RockfallManager {
	
	private static int MAX_FPC, SERVER_PORT;
	
	private ArrayList<FPC> fpcList;
	
	private static boolean firstRun = true;
	
	public RockfallManager() {
		PerlaRuntime runtime = PerlaRuntime.getDefaultRuntime();
		if(runtime.containsKey("DSPIC_NUM")){
			MAX_FPC = new Integer(runtime.getProperty("DSPIC_NUM")) + 1;			
		}
		else {
			MAX_FPC = 8;
		}
		
		if(runtime.containsKey("SERVER_PORT")){
			SERVER_PORT = new Integer(runtime.getProperty("SERVER_PORT"));			
		}
		else {
			SERVER_PORT = 5606;
		}
		
		
		fpcList = new ArrayList<FPC>();
		
		// Inizializzo il server
		Server s = new Server(SERVER_PORT);
		s.start();
		
		IntecFpc intecFpc = new  IntecFpc(s.getFpcPipes(0));
		fpcList.add(intecFpc);
		Thread intecDbDump = new Thread(new IntecDatabaseDump(intecFpc.registerQuery(null)));
		intecDbDump.start();
		
		// Istanzio ed aggancio le fpc al server ed al database dumper
		for (int i = 1; i < MAX_FPC; i++){
			DSPicFPC tTempFpc = new DSPicFPC(s.getFpcPipes(i), i);
			fpcList.add(tTempFpc);
			Thread dbDump = new Thread(new DatabaseDump(tTempFpc.registerQuery(null)));
			dbDump.start();
		}
	}
	
	public Iterator<FPC> getListIterator() {
		return fpcList.iterator();
	}
	
	public void executeQuery(String query) {
		
		StringReader reader = new StringReader(query);
		
		
		if (firstRun) {
			new Parser(new BufferedReader(reader));
			firstRun = false;
			
		} else {
			Parser.ReInit(new BufferedReader(reader));
		}
		
		try {
			ArrayList<Query> arrayList = Parser.StatementSequence();
			Iterator<Query> parsedQueryIterator = arrayList.iterator();
			while(parsedQueryIterator.hasNext()) {
				ArrayList<PairValue<String, ? extends Constant>> pAttributeToSetList = new ArrayList<PairValue<String, ? extends Constant>>();
				Query parsedQuery = parsedQueryIterator.next(); 
				QueryAnalyzer queryAnalizer = new QueryAnalyzer(parsedQuery);
			
				for (String tAttributeToSet : queryAnalizer.getAttributeToSet().keySet()){
					pAttributeToSetList.add(new PairValue<String, Constant>(tAttributeToSet, queryAnalizer.getAttributeToSet().get(tAttributeToSet)));
				}
			
				for (ConstantID id : queryAnalizer.getDeviceToSetID()) {
					fpcList.get(id.getValueInt()).setUpdateAttributes(pAttributeToSetList);
				}
			}	
		} catch (ParseException e) {
			e.printStackTrace();
		} 
	}
}
